package _07_串;

public class _5_最长回文子串 {


    public static void main(String[] args) {

        _5_最长回文子串 v = new _5_最长回文子串();

        System.out.println(v.longestPalindrome("babad"));

    }

    // 中心扩展发展
    public String longestPalindrome(String s) {
        if (s.length() < 2) return s;
        char[] chars = s.toCharArray();
        int length = chars.length;
        int maxLen = 1;
        int begin = 0;
        for (int i = 0; i < length; i++) {
            int left = i - 1;
            int right = i;
            // 找到第一个不等于当前字符
            while (right < length && chars[i] == chars[right]) right++;
            // 对比字符
            while (left >= 0 && right < length && chars[left] == chars[right]) {
                left--;
                right++;
            }

            int len = right - ++left;
            if (len > maxLen) {
                maxLen = len;
                begin = left;
            }
        }
        return new String(chars, begin, maxLen);
    }

    // 动态规划思想
    public String longestPalindrome2(String s) {
        if (s.length() < 2) return s;
        char[] chars = s.toCharArray();
        int length = chars.length;
        int maxLen = 1;
        int begin = 0;
        // dp[i][j] 表示第i，j字符组成的字符串是否为回文串
        boolean[][] dp = new boolean[length][length];
        for (int i = length - 1; i >= 0; i--) {
            for (int j = i; j < length; j++) {
                int len = j - i + 1;
                if (chars[i] != chars[j]) {
                    dp[i][j] = false;
                }
                if (len <= 3) {
                    dp[i][j] = true;
                } else {
                    dp[i][j] = dp[i + 1][j - 1];
                }
                if (dp[i][j] && len > maxLen) {
                    maxLen = len;
                    begin = i;
                }
            }
        }
        return new String(chars, begin, maxLen);
    }

    public String longestPalindrome1(String s) {
        if (s.length() < 1) {
            return s;
        }
        char[] chars = s.toCharArray();
        int length = chars.length;
        // dp[i][j] 表示第i到j串的最大回文串长度
        boolean[][] dp = new boolean[length][length];
        for (int i = 0; i < length; i++) {
            // 对于dp[i][j]，最大回文串的长度就为1
            dp[i][i] = true;
        }
        int subBegin = 0;
        int subEnd = 0;
        int max = 1;
        for (int len = 2; len <= length; len++) {
            for (int start = 0; start < length; start++) {
                // 计算截止范围
                int end = start + len - 1;
                if (end >= length) {
                    // 超出预期值
                    break;
                }
                if (chars[start] != chars[end]) {
                    dp[start][end] = false;
                } else {
                    if (end - start < 3) {
                        dp[start][end] = true;
                    } else {
                        dp[start][end] = dp[start + 1][end - 1];
                    }
                }

                if (dp[start][end] && len > max) {
                    max = len;
                    subBegin = start;
                    subEnd = end;
                }
            }
        }
        return new String(chars, subBegin, subEnd - subBegin + 1);
    }

}
